package com.chagee.channel.api.bo.lark;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.annotation.JSONField;
import com.chagee.channel.api.bo.FastJsonSerializer.EpochMillSerializer;
import com.chagee.channel.api.bo.FastJsonSerializer.JsonArrayDeserializer;
import com.chagee.channel.api.enums.LarkApprovalNodeStatusEnum;
import com.chagee.channel.api.enums.LarkApprovalNodeTypeEnum;
import com.chagee.channel.api.enums.LarkApprovalStatusEnum;
import com.chagee.channel.api.enums.LarkApprovalTimeLineTypeEnum;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

/**
 * 审核详情
 *
 * @author: chang.jiawei
 * @date: 2024/01/17
 */
@Data
@Accessors(chain = true)
public class ApprovalInstanceDetailBO implements Serializable {

    private static final long serialVersionUID = -4270355725457336331L;

    @ApiModelProperty("飞书审批id")
    private String id;

    @ApiModelProperty("审批实例code")
    private String instanceCode;

    @ApiModelProperty("审批定义code")
    private String approvalCode;

    @ApiModelProperty("审批单编号")
    private String serialNumber;

    @ApiModelProperty("发起审批用户")
    private String userId;

    @ApiModelProperty("发起审批用户")
    private String openId;

    @ApiModelProperty("审批实例状态")
    //@JSONField(deserializeUsing = LarkApprovalStatusDeserializer.class)
    private LarkApprovalStatusEnum status;

    @ApiModelProperty("表单详情,详见：https://open.feishu.cn/document/server-docs/approval-v4/instance/get")
    @JSONField(serializeUsing = JsonArrayDeserializer.class)
    private JSONArray form;

    @ApiModelProperty("审批创建时间")
    @JSONField(serializeUsing = EpochMillSerializer.class)
    private LocalDateTime startTime;

    @ApiModelProperty("审批完成时间")
    @JSONField(serializeUsing = EpochMillSerializer.class)
    private LocalDateTime endTime;

    @ApiModelProperty("单据是否被撤销")
    private Boolean reverted;

    @ApiModelProperty("评论详情")
    private List<ApprovalCommentDetailVO> commentList;

    @ApiModelProperty("审核流详情")
    private List<ApprovalFlowDetailVO> taskList;

    @ApiModelProperty("时间线")
    private List<ApprovalTimelineDetailVO> timeline;

    /**
     * 审核流详情
     *
     * @author: chang.jiawei
     * @date: 2024/01/17
     */
    @Data
    @Accessors(chain = true)
    public static class ApprovalFlowDetailVO implements Serializable {

        private static final long serialVersionUID = -2276217184485721316L;
        @ApiModelProperty("审核节点任务id")
        private String id;

        @ApiModelProperty("审核节点id")
        private String nodeId;

        @ApiModelProperty("审核节点自定义id")
        private String customNodeId;

        @ApiModelProperty("审核节点名称")
        private String nodeName;

        @ApiModelProperty("审核人id")
        private String userId;

        @ApiModelProperty("审核类型")
        private LarkApprovalNodeTypeEnum type;

        @ApiModelProperty("审核节点状态")
        private LarkApprovalNodeStatusEnum status;

        @ApiModelProperty("任务开始时间")
        @JSONField(serializeUsing = EpochMillSerializer.class)
        private LocalDateTime startTime;

        @ApiModelProperty("任务完成时间")
        @JSONField(serializeUsing = EpochMillSerializer.class)
        private LocalDateTime endTime;
    }

    /**
     * 审核评论详情
     *
     * @author: chang.jiawei
     * @date: 2024/01/17
     */
    @Data
    @Accessors(chain = true)
    public static class ApprovalCommentDetailVO implements Serializable {

        private static final long serialVersionUID = 1928279908635578774L;
        /**
         * 创建时间
         */
        @ApiModelProperty("创建时间")
        @JSONField(name = "create_time", serializeUsing = EpochMillSerializer.class)
        private LocalDateTime creatTime;

        /**
         * 评论人id
         */
        @ApiModelProperty("评论人id")
        private String userId;

        /**
         * 评论内容
         */
        @ApiModelProperty("评论内容")
        private String comment;

        /**
         * 评论文件
         */
        @ApiModelProperty("评论文件")
        private List<FileVO> files;
    }

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public static class FileVO implements Serializable {

        private static final long serialVersionUID = 7838994921989900574L;
        /**
         * 文件路径
         */
        private String url;

        /**
         * 文件名称
         */
        private String title;

        /**
         * 文件大小，byte
         */
        private Long fileSize;

        /**
         * 文件类型
         */
        private String type;
    }

    /**
     * 审核时间线
     *
     * @author: chang.jiawei
     * @date: 2024/01/17
     */
    @Data
    @Accessors(chain = true)
    public static class ApprovalTimelineDetailVO implements Serializable {

        private static final long serialVersionUID = 3480971951402370592L;
        @ApiModelProperty("任务id")
        private String taskId;
        /**
         * 创建时间
         */
        @ApiModelProperty("创建时间")
        @JSONField(name = "create_time", serializeUsing = EpochMillSerializer.class)
        private LocalDateTime creatTime;

        /**
         * 评论人id
         */
        @ApiModelProperty("评论人id")
        private String userId;

        /**
         * 产生 task 的节点 key
         */
        @ApiModelProperty("产生 task 的节点 key")
        private String nodeKey;

        /**
         * 理由
         */
        @ApiModelProperty("理由")
        private String comment;

        /**
         * 评论文件
         */
        @ApiModelProperty("评论文件")
        private List<FileVO> files;

        /**
         * https://open.feishu.cn/document/server-docs/approval-v4/instance/get
         */
        @ApiModelProperty("动态类型")
        private LarkApprovalTimeLineTypeEnum type;
    }

    @Data
    @Accessors(chain = true)
    public static class RejectResult implements Serializable {

        private static final long serialVersionUID = -3940990353558263562L;
        private String comment;

        private List<FileVO> files;
    }

    public RejectResult newestRejectResult() {
        return Optional.ofNullable(this.timeline).orElse(Collections.emptyList()).stream().filter(t -> t.getType() == LarkApprovalTimeLineTypeEnum.REJECT).max(Comparator.comparing(
            ApprovalTimelineDetailVO::getCreatTime)).map(t -> new RejectResult().setComment(t.getComment()).setFiles(t.getFiles())).orElse(null);
    }

    public Optional<ApprovalFlowDetailVO> currentApproveTask() {
        return Optional.ofNullable(this.taskList).orElse(Collections.emptyList()).stream().filter(t -> LarkApprovalNodeStatusEnum.PENDING.equals(t.getStatus())).findFirst();
    }

    public Optional<String> latestApproverId() {
        return Optional.ofNullable(this.taskList).orElse(Collections.emptyList()).stream().filter(t -> LarkApprovalNodeStatusEnum.APPROVED.equals(t.getStatus()))
            .sorted(Comparator.comparing(ApprovalFlowDetailVO::getEndTime).reversed()).map(ApprovalFlowDetailVO::getUserId).findFirst();
    }

    public List<ApprovalFlowDetailVO> currentApproveTasks() {
        return Optional.ofNullable(this.taskList).orElse(Collections.emptyList()).stream().filter(t -> LarkApprovalNodeStatusEnum.PENDING.equals(t.getStatus()))
            .collect(Collectors.toList());
    }

}
